#include "include.h"
#include "ts32fx_hal_eflash_bsp.h"

/** @addtogroup Template_Project
  * @{
  */
  
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Public variables ---------------------------------------------------------*/

/**********************************************************/
#define USER_BUFF_LEN          8               //Please user fixed this define

/*********************************************************/
/*********Please user don't fixed this param!!!**************/
#define USER_REAL_DATA_BUFF_LEN       (USER_BUFF_LEN+1+1)                 //add flag(0x5A is write flag) and  CS 
#define USER_BUFF_WORD_NUM            ((USER_REAL_DATA_BUFF_LEN + 3)/4)   //add flag(0x5A is write flag) and  CS 
#define USER_BUFF_BYTE_NUM            (USER_BUFF_WORD_NUM * 4)
#define USER_BUFF_SEARCH_MAX_INDEX    (LL_EF_SECTOR_SIZE / USER_BUFF_BYTE_NUM)
#define USER_PARAM_SECTOR0_INDEX      (LL_EF_MAIN_SECTOR_NUM -3)         //sector_61
#define USER_PARAM_SECTOR1_INDEX      (LL_EF_MAIN_SECTOR_NUM -2)         //sector 62
#define USER_PARAM_SECTOR0_ADDR       (USER_PARAM_SECTOR0_INDEX * LL_EF_SECTOR_SIZE) //sector_61 * 512 = 31232 = 0x7A00
#define USER_PARAM_SECTOR1_ADDR       (USER_PARAM_SECTOR1_INDEX * LL_EF_SECTOR_SIZE) //sector_62 * 512 = 31232 = 0x7C00
/***********************************************************/
/**
  * @brief  hal_user_eflash_init
  * @param  None
  * @retval None
  * @note   Flag + data_buf + cs
  */
void hal_user_eflash_init(void)
{
    TYPE_LL_EFLASH_INIT eflash_init;
    memset(&eflash_init, 0x00, sizeof(eflash_init));
    /* Initialize the relevant variables  */
    ll_eflash_init(EFLASH, &eflash_init);
    ll_eflash_cache_set(EFLASH, true);
    ll_eflash_prefetch_set(EFLASH, true);
}
/**
  * @brief  hal_user_eflash_write_param
  * @param  buffer_data:user data buffer   data_len: byte num
  * @retval None
  * @note   Flag + data_buf + cs
  */
void hal_user_eflash_write_param(u8 *buffer_data,u8 data_len)
{
	u8 index =0;
	u8 i = 0;
	u8 user_all_data[USER_BUFF_BYTE_NUM]__attribute__((aligned(4))) = {0x00};
	u32 *pBuf = NULL;
	u8 user_data_cs = 0;
	u32 prog_addr = 0;
	
	user_all_data[0] = 0x5A;                               //set flag is 0x5A
	memcpy(&user_all_data[1], buffer_data, data_len);      //copy user_data
	
	for(i=0; i<USER_BUFF_LEN; i++){                        //cal add_cs
		user_data_cs += buffer_data[i];                   
	}
	user_all_data[USER_REAL_DATA_BUFF_LEN-1] = user_data_cs;//add_user_cs
	pBuf = (u32 *)user_all_data;                         //pBuff point user_all_data
	
	for(index=0; index<USER_BUFF_SEARCH_MAX_INDEX; index++){//seach effective space
		for(i=0; i<USER_BUFF_WORD_NUM; i++){
			if(LL_EFLASH_DATA_GET(USER_PARAM_SECTOR0_ADDR + index * USER_BUFF_BYTE_NUM +i*4)==0xFFFFFFFF){
				continue;
			}else{
				break;
			}
		}
		if(i==USER_BUFF_WORD_NUM){                         //effective space
			break;
		}
	}
	
	if(index == USER_BUFF_SEARCH_MAX_INDEX){                //not effective space
		ll_eflash_erase_one_sector(EFLASH, USER_PARAM_SECTOR0_INDEX);  //erase this sector
		index = 0;
	}
	
	if(0 != index){
        for(i=0; i<index; i++){
          ll_eflash_prog_one_data(EFLASH, USER_PARAM_SECTOR0_ADDR + i* USER_BUFF_BYTE_NUM, 0xFFFFFF00); //clr flag
        }
	}
	
	prog_addr = USER_PARAM_SECTOR0_ADDR + USER_BUFF_BYTE_NUM * index;
	for(i = 0; i < USER_BUFF_BYTE_NUM; i+=4){       //write_user_param
		ll_eflash_prog_one_data(EFLASH, prog_addr + i, *pBuf++);
	}
}

/**
  * @brief  hal_user_eflash_read_param
  * @param  buffer_data:user data buffer   data_len: byte num
  * @retval read data effective result
  * @note   TRUE is effective ,FALSE is not effective
  */
bool hal_user_eflash_read_param(u8 *buffer_data, u8 data_len)
{
	u8 index =0;
	u8 i = 0;
	u8 user_data_cs = 0;
	u32 user_word_data[USER_BUFF_WORD_NUM] = {0};
	u8 *p_buf = NULL;
	u32 flag_word = 0;
	for(index=0; index<USER_BUFF_SEARCH_MAX_INDEX; index++){//seach effective flag
		flag_word = LL_EFLASH_DATA_GET(USER_PARAM_SECTOR0_ADDR + index * USER_BUFF_BYTE_NUM);
		if((flag_word&0x000000FF) == 0x0000005A){
			for(i=0;i<USER_BUFF_WORD_NUM; i++){
				user_word_data[i] = LL_EFLASH_DATA_GET(USER_PARAM_SECTOR0_ADDR + index * USER_BUFF_BYTE_NUM +i*4);
			}
			break;
		}else{
			continue;
		}
	}
	if(index == USER_BUFF_SEARCH_MAX_INDEX)    //don't effective data
	{
		return FALSE;
	}
	p_buf = (u8 *)user_word_data;
	
	for(i=0; i < USER_BUFF_LEN; i++){
		user_data_cs += p_buf[i+1];
	}
	
	if(user_data_cs == p_buf[USER_REAL_DATA_BUFF_LEN-1]){
		memcpy(buffer_data, &p_buf[1], data_len);
		return TRUE;
	}else{
		return FALSE;
	}
}
